package com.woniuxy.project115.kaer.tenant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.project115.kaer.commons.util.OSSUtil;
import com.woniuxy.project115.kaer.tenant.config.WebSocketServer;
import com.woniuxy.project115.kaer.tenant.dto.ApplicationAttachmentDto;
import com.woniuxy.project115.kaer.tenant.dto.SettledApplicationDto;
import com.woniuxy.project115.kaer.tenant.entity.ApplicationAttachment;
import com.woniuxy.project115.kaer.tenant.entity.SettledApplication;
import com.woniuxy.project115.kaer.tenant.entity.TenantInfo;
import com.woniuxy.project115.kaer.tenant.entity.TenantStore;
import com.woniuxy.project115.kaer.tenant.mapper.ApplicationAttachmentMapper;
import com.woniuxy.project115.kaer.tenant.mapper.SettledApplicationMapper;
import com.woniuxy.project115.kaer.tenant.mapper.TenantInfoMapper;
import com.woniuxy.project115.kaer.tenant.mapper.TenantStoreMapper;
import com.woniuxy.project115.kaer.tenant.param.ApproveApplicationParam;
import com.woniuxy.project115.kaer.tenant.param.SubmitApplicationParam;
import com.woniuxy.project115.kaer.tenant.service.SettledApplicationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.project115.kaer.tenant.util.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author HuH
 * @since 2025年02月20日
 */
@Service
public class SettledApplicationServiceImpl extends ServiceImpl<SettledApplicationMapper, SettledApplication> implements SettledApplicationService {
    @Resource
    private SettledApplicationMapper settledApplicationMapper;

    @Resource
    private TenantInfoMapper tenantInfoMapper;

    @Resource
    private ApplicationAttachmentMapper applicationAttachmentMapper;

    @Resource
    private TenantStoreMapper tenantStoreMapper;

    @Override
    public String uploadLogo(MultipartFile file) throws Exception {
        //判断上传的文件的真实类型
        //取出上传的文件的前4个字节，其中保存了文件的类型信息
        InputStream is = file.getInputStream();
        byte[] fileHeader=new byte[4];
        is.read(fileHeader);
        //调用API判断文件类型
        if(!(OSSUtil.isJpg(fileHeader)||OSSUtil.isPng(fileHeader))){
            throw new Exception("文件类型不支持");
        }
        //先获取文件的后缀名
        String suffix = StringUtils.getFilenameExtension(file.getOriginalFilename());
        String prefix= UUID.randomUUID().toString();
        //实现文件上传
        String url = OSSUtil.uploadFile(file.getInputStream(), prefix + "." + suffix, "kaer-service");
        return url;
    }

    @Override
    public void submitApplication(SubmitApplicationParam param, Integer tenantInfoId) throws Exception {
        SettledApplication application1 = settledApplicationMapper.selectOne(
                new QueryWrapper<SettledApplication>()
                        .eq("tenant_info_id", tenantInfoId)
                        .ne("state", Data.APPLICATION_REJECTED));
        if (application1 != null) {
            throw new Exception("您已经提交过申请，请勿重复提交");
        }

        //创建一个集合存储附件
        List<ApplicationAttachment> list = new ArrayList<>();
        for (MultipartFile file : param.getFiles()) {
            //判断文件是否为空
            if (file.isEmpty()) {
                throw new Exception("文件不能为空");
            }

            //判断文件类型是否为图片（.doc/.docx/.pdf/.jpg/.png）
            byte[] bytes = new byte[4];
            file.getInputStream().read(bytes);
            if (!(OSSUtil.isDoc(file) ||OSSUtil.isDocx(bytes) || OSSUtil.isPdf(bytes) || OSSUtil.isJpg(bytes) || OSSUtil.isPng(bytes))) {
                throw new Exception("文件类型错误");
            }

            //获取完整文件名
            String filename = file.getOriginalFilename();
            //获取文件后缀名
            String suffix = FileUtil.extName(filename);
            //生成一个随机的文件名
            String name = UUID.randomUUID().toString() + "." + suffix;
            //文件上传
            String url = OSSUtil.uploadFile(file.getInputStream(), name, "kaer-service");
            ApplicationAttachment attachment = new ApplicationAttachment();
            attachment.setAttachmentAddress(url)
                    .setAttachmentName(filename)
                    .setServerName("阿里云服务器");
            list.add(attachment);
        }

        SettledApplication application;
        if (param.getApplicationId() == 0) {//首次提交申请
            TenantInfo tenantInfo = tenantInfoMapper.selectById(tenantInfoId);
             application = new SettledApplication();
            application.setCommitTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                    .setTenantInfoId(tenantInfoId)
                    .setCommitName(tenantInfo.getName())
                    .setCommitPhone(tenantInfo.getPhone())
                    .setStoreName(param.getStoreName())
                    .setStoreLogo(param.getStoreLogo())
                    .setBusinessScope(param.getBusinessScope())
                    .setAddress(param.getAddress())
                    .setLongitude(param.getLongitude())
                    .setLatitude(param.getLatitude())
                    .setRemarks(param.getRemarks())
                    .setState(Data.APPLICATION_WAIT_APPROVAL);
            settledApplicationMapper.insert(application);
        } else {//修改被驳回的申请
            application = settledApplicationMapper.selectById(param.getApplicationId());
            application.setStoreName(param.getStoreName())
                    .setStoreLogo(param.getStoreLogo())
                    .setBusinessScope(param.getBusinessScope())
                    .setAddress(param.getAddress())
                    .setLongitude(param.getLongitude())
                    .setLatitude(param.getLatitude())
                    .setRemarks(param.getRemarks())
                    .setState(Data.APPLICATION_WAIT_APPROVAL);
            settledApplicationMapper.updateById(application);
        }

        for (ApplicationAttachment attachment : list) {
            attachment.setApplicationId(application.getApplicationId());
            applicationAttachmentMapper.insert(attachment);
        }
    }

    @Override
    public List<SettledApplicationDto> getPendingApplication() throws Exception {
        List<SettledApplication> list = settledApplicationMapper.selectList(
                new QueryWrapper<SettledApplication>()
                        .eq("state", Data.APPLICATION_WAIT_APPROVAL)
        );
        ArrayList<SettledApplicationDto> dtos = new ArrayList<>();
        for (SettledApplication application : list) {
            SettledApplicationDto dto = BeanUtil.toBean(application, SettledApplicationDto.class);
            dtos.add(dto);
        }
        return dtos;
    }

    @Override
    public void approveApplication(ApproveApplicationParam param) throws Exception {
        SettledApplication application = settledApplicationMapper.selectById(param.getApplicationId());
        if (application == null) {
            throw new Exception("申请不存在");
        }
        if (application.getState() == Data.APPLICATION_APPROVED || application.getState() == Data.APPLICATION_REJECTED) {
            throw new Exception("申请已被审核");
        }

        if (param.getState() == Data.APPLICATION_APPROVED) {//通过
            application.setState(Data.APPLICATION_APPROVED);
            application.setReviewer(param.getReviewer())
                    .setReviewTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
            settledApplicationMapper.updateById(application);

            TenantStore store = BeanUtil.toBean(application, TenantStore.class);
            TenantInfo tenantInfo = tenantInfoMapper.selectById(application.getTenantInfoId());

            store.setStoreContacts(tenantInfo.getName())
                    .setFirstOpenTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                    .setStorePhone(tenantInfo.getPhone())
                    .setServiceNumber(0)
                    .setScore(0.0)
                    .setIsOpen(Data.STORE_BUSINESS_STATE_OFFLINE);
            tenantStoreMapper.insert(store);

            tenantInfo.setStoreId(store.getStoreId());
            tenantInfo.setStoreName(application.getStoreName());
            tenantInfoMapper.updateById(tenantInfo);

        } else if (param.getState() == Data.APPLICATION_REJECTED) {//驳回
            application.setState(Data.APPLICATION_REJECTED)
                    .setReviewer(param.getReviewer())
                    .setReviewTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                    .setRejectReason(param.getRejectReason());
            settledApplicationMapper.updateById(application);
        }

        WebSocketServer.sendInfo("您的店铺入驻申请已被审核，请及时查看。", String.valueOf(application.getTenantInfoId()));
    }

    @Override
    public List<SettledApplication> getApplication(Integer tenantInfoId) throws Exception {
        return settledApplicationMapper.selectList(
                new QueryWrapper<SettledApplication>()
                        .eq("tenant_info_id", tenantInfoId)
        );
    }

}
